//#define __FORCE_TRACE__
//#define __FORCE_DEBUG__
//#define __FORCE_INFO__
#define THIS_FILE "server\fn_serverSetupTakeOver.sqf"
#include <tmf_constants.h>
#include <tmf_macros.h>

TRACE_1("Start",_this);
TMFPROFILERSTART;

private ["_object","_action","_instance_id","_action_id"];
DEFAULT_PARAM(_object,TMF_REGISTER_OBJECT,objNull);
DEFAULT_PARAM(_action,TMF_REGISTER_ACTION,[]);
DEFAULT_PARAM(_instance_id,TMF_REGISTER_INSTANCE,TMF_SERVER_INSTANCE_ID);
_action_id = [_action] call FFUNC(actionGetID);

if (!isnull _object) then {
	_evt_idx = _object addEventHandler ["killed", Format["[_this, %1] call %2;",_action_id,QUOTE(FFUNC(eventObjectiveTakeOverKilled))]];
	[_object,_action,"TAKEOVER_KILLED_EVENT",_evt_idx] call FFUNC(actionSetLocal);

	_this spawn {
		private ["_object","_instance_id","_entities","_taken","_hold_count","_count_owners","_count_takers","_count_soldiers","_action","_parameters","_zone_size","_takenover_msg","_lost_msg","_shared_takeover","_hold_time"
				,"_action_id","_owner_side","_taker_side","_takenover_code","_lost_code","_evt_idx","_share_dist","_grp","_leader","_grps","_wp","_taken_time"];
		DEFAULT_PARAM(_object,TMF_REGISTER_OBJECT,objNull);
		DEFAULT_PARAM(_action,TMF_REGISTER_ACTION,[]);
		DEFAULT_PARAM(_instance_id,TMF_REGISTER_INSTANCE,TMF_SERVER_INSTANCE_ID);
		_action_id = [_action] call FFUNC(actionGetID);
		_base_conquer_timeout = ["BASE_CONQUERED_TIMEOUT",30] call FFUNC(getFrameworkValue);
		TRACE_1("Action",_action);
		_parameters = [_action] call FFUNC(actionGetParams);
		_zone_size = [_parameters, "ZONE_SIZE", 30] call CFUNC(hashGet);
		_takenover_msg = [_parameters, "TAKEN_MSG", ""] call CFUNC(hashGet);
		_lost_msg = [_parameters, "LOST_MSG", ""] call CFUNC(hashGet);
		_shared_takeover = [_parameters, "SHARED_VAR", ""] call CFUNC(hashGet);
		_hold_time = [_parameters, "HOLD_TIME", _base_conquer_timeout] call CFUNC(hashGet);
		_owner_side = [_parameters, "OWNER_SIDE", GVAR(side_enemy)] call CFUNC(hashGet);
		_taker_side = [_parameters, "TAKER_SIDE", GVAR(side_own)] call CFUNC(hashGet);
		_takenover_code = [_parameters, "TAKEN_CODE", ""] call CFUNC(hashGet);
		_lost_code = [_parameters, "LOST_CODE", ""] call CFUNC(hashGet);
		_share_dist = [_parameters, "SHARED_DIST", 300] call CFUNC(hashGet);

		if (typename _takenover_msg == typename "") then {_takenover_msg = [_takenover_msg];};
		if (typename _lost_msg == typename "") then {_lost_msg = [_lost_msg];};
		_taken = false;
		_taken_time = 0;
		if (!isnil "KRON_UPS_sharedist") then { if (KRON_UPS_sharedist > _share_dist)  then { _share_dist = KRON_UPS_sharedist; }; };

		if (!isNil "_shared_takeover") then {
			if (_shared_takeover != "") then {
				[_instance_id,_shared_takeover,_taken] call FFUNC(setMissionJIPVar);
				[QGVAR(all_var), [_instance_id,_shared_takeover,_taken],THIS_FILE_] call NFUNC(callEvent);
			};
		};
	
		if (typename _owner_side == typename []) then {
			for [{_i = 0},{_i < count _owner_side},{_i = _i + 1}] do {
				if (typename (_owner_side select _i) == typename "") then {
					_owner_side set [_i, (switch {toupper((_owner_side select _i))} do { case "EAST": {east}; case "WEST": {west}; case "GUER": {resistance};	case "CIV": {civilian};	default{ GVAR(side_enemy)};	})];
				};
			};
		} else {
			if (typename _owner_side == typename "") then {
				_owner_side = switch {toupper(_owner_side)} do { case "EAST": {east}; case "WEST": {west}; case "GUER": {resistance};	case "CIV": {civilian};	default{ GVAR(side_enemy)};	};
			};
			_owner_side = [_owner_side];
		};
		if (typename _taker_side == typename []) then {
			for [{_i = 0},{_i < count _taker_side},{_i = _i + 1}] do {
				if (typename (_taker_side select _i) == typename "") then {
					_taker_side set [_i, (switch {toupper((_taker_side select _i))} do { case "EAST": {east}; case "WEST": {west}; case "GUER": {resistance};	case "CIV": {civilian};	default{ GVAR(side_own)};	})];
				};
			};
		} else {
			if (typename _taker_side == typename "") then {
				_taker_side = switch {toupper(_taker_side)} do { case "EAST": {east}; case "WEST": {west}; case "GUER": {resistance};	case "CIV": {civilian};	default{ GVAR(side_own)};	};
			};
			_taker_side = [_taker_side];
		};

		if (_share_dist > 300) then {_share_dist = 300;};
		while {alive _object && !isnull _object} do {
			_entities = (getPos _object) nearEntities [["Man","LandVehicle"], _zone_size];
			
			_count_owners = 0;
			{ _count_owners = _count_owners + (_x countSide _entities);
			} foreach _owner_side;
			_count_takers = 0;
			{ _count_takers = _count_takers + (_x countSide _entities);
			} foreach _taker_side;

			// If taker inside we take the bunker
			if ((_count_owners <= 0) and (_count_takers > 0)) then {
				_hold_count = _hold_count + 1;
			};
			// If owner inside, we reown the bunker, two times faster (its the owner after all)
			if ((_count_owners > 0) and (_count_takers <= 0)) then {
				_hold_count = _hold_count - 2;
			};
			// If nobody inside, we set the variable back to the current status
			if ((_count_owners == 0) and (_count_takers == 0)) then {
				if (_taken) then { _hold_count = _hold_time }
				else { _hold_count = 0 };
			};
			if (_hold_count <= 0) then {_hold_count = 0};
			if (_hold_count >= _hold_time) then {_hold_count = _hold_time};
			if ((_hold_count >= _hold_time) && !_taken) then {
				_taken = true;
				if (!isNil "_takenover_msg") then {
					if (count _takenover_msg > 0) then {[QGVAR(all_message),[_takenover_msg,"all",objNull,"hq"],THIS_FILE_] call NFUNC(callEvent);};
				};
				if (!isNil "_shared_takeover") then {
					if (_shared_takeover != "") then {
						[_instance_id,_shared_takeover,_taken] call FFUNC(setMissionJIPVar);
						[QGVAR(all_var), [_instance_id,_shared_takeover,_taken],THIS_FILE_] call NFUNC(callEvent);
					};
				};
				if (_takenover_code != "") then {
					[QGVAR(all_execute),[_takenover_code,_object,_action],THIS_FILE_] call NFUNC(callEvent);
				};			

				// When a point gets taken over, we send the nearest groups to it
				if (([[(getPos _object),(_zone_size / 2)], _owner_side, _share_dist,["Man","Car","Motorcycle"]] call FFUNC(convergeUnits)) > 0) then {
					_taken_time = time;
				};
			};
			if ((_hold_count <= 0) && _taken) then {
				_taken = false;
				if (!isNil "_lost_msg") then {
					if (count _lost_msg > 0) then {[QGVAR(all_message),[_lost_msg,"all",objNull,"hq"],THIS_FILE_] call NFUNC(callEvent);};
				};
				if (!isNil "_shared_takeover") then {
					if (_shared_takeover != "") then {
						[_instance_id,_shared_takeover,_taken] call FFUNC(setMissionJIPVar);
						[QGVAR(all_var), [_instance_id,_shared_takeover,_taken],THIS_FILE_] call NFUNC(callEvent);
					};
				};
				if (_lost_code != "") then {
					[QGVAR(all_execute),[_lost_code,_object,_action],THIS_FILE_] call NFUNC(callEvent);
				};			
			};
			// If still taken after 5 minutes, we call more groups.
			if (_taken && ((time - _taken_time) > 300)) then {
				// Continue to call units if still not retaken but only men who can actually enter
				if (([[(getPos _object),(_zone_size / 2)], _owner_side, _share_dist,["Man"]] call FFUNC(convergeUnits)) > 0) then {
					// If a group was called, the function returns a value above 0. This will reset the check time.
					_taken_time = time;
				};
			};
			// This helps keeping the CPU activity low
			if (_count_owners == 0 && _count_takers == 0) then { sleep 5 };
			if (_count_owners > 0 && _count_takers == 0 && !_taken) then { sleep 5 };
			if (_count_takers > 0 && _count_owners == 0 && _taken) then { sleep 5 };
			sleep 1;
		};
	};
};
TRACE("End");
TMFPROFILERSTOP;